<?php

namespace Core\Route;

use App\Kernel;

/**
 * 每个中间件都new 2次浪费内存
 */
class MiddlewareExecute extends Kernel
{
    protected $container;

    public function run(array $middle)
    {
        $res = $this->runGlobal();
        if ($res !== true) {
            return $res;
        }

        $res = $this->runGroup($middle);
        if ($res !== true) {
            return $res;
        }

        $res = $this->runCustom($middle);
        if ($res !== true) {
            return $res;
        }

        return $res;
    }

    /**
     * run after handle
     */
    public function runAfter()
    {
        foreach (static::$afterMiddleware as $className) {
            $res = $this->runClassHandle($className);
            if ($res !== true) {
                return $res;
            }
        }

        return true;
    }

    /**
     * 执行分组的中间件
     */
    public function runGroup($middle)
    {
        foreach ($middle as $name) {
            if (array_key_exists($name, self::$middlewareGroups)) {
                foreach (self::$middlewareGroups[$name] as $key => $className) {
                    $res = $this->runClassHandle($className);
                    if ($res !== true) {
                        return $res;
                    }
                }
            }
        }

        return true;
    }

    /**
     * 执行自定义中间件
     */
    public function runCustom($middle)
    {
        foreach ($middle as $name) {
            if (array_key_exists($name, self::$routeMiddleware)) {
                $res = $this->runClassHandle(self::$routeMiddleware[$name]);
                if ($res !== true) {
                    return $res;
                }
            }
        }

        return true;
    }

    /**
     * 执行全局中间件
     */
    public function runGlobal()
    {
        foreach (static::$middleware as $className) {
            $res = $this->runClassHandle($className);
            if ($res !== true) {
                return $res;
            }
        }

        return true;
    }

    /**
     * 执行方法
     */
    protected function runClassHandle($className)
    {
        $obj = new $className();
        return $obj->handle();
    }
}
